package com.dctp.common.utils;

import java.util.regex.Pattern;

/**
 * 字段校验工具类
 */
public class ValidateUtil {

    // ---------------------- 通用正则表达式 ----------------------
    
    /** 中国大陆手机号正则 (13/14/15/16/17/18/19开头) */
    private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";
    
    /** 邮箱正则 (兼容大多数常见格式) */
    private static final String EMAIL_REGEX = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}$";
    
    /** 身份证正则 (15位或18位，18位需校验最后一位) */
    private static final String ID_CARD_REGEX = "(^\\d{15}$)|(^\\d{17}([0-9]|X|x)$)";
    
    /** 中国大陆车牌号正则 (新能源+传统车牌) */
    private static final String LICENSE_PLATE_REGEX = "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]" +
            "([A-HJ-NP-Z](([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))|" +
            "([A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}))";

    /** 中文姓名正则 (2-10个汉字，支持少数民族姓名中的点) */
    private static final String CHINESE_NAME_REGEX = "^[\\u4e00-\\u9fa5]{2,10}(·[\\u4e00-\\u9fa5]+)*$";

    // ---------------------- 校验方法 ----------------------

    /**
     * 校验手机号
     * @param phone 手机号 (需纯数字，不含空格、+86等前缀)
     */
    public static boolean isPhone(String phone) {
        return match(phone, PHONE_REGEX);
    }

    /**
     * 校验邮箱
     */
    public static boolean isEmail(String email) {
        return match(email, EMAIL_REGEX);
    }

    /**
     * 校验身份证号 (格式 + 校验码)
     */
    public static boolean isIdCard(String idCard) {
        if (!match(idCard, ID_CARD_REGEX)) {
            return false;
        }
        // 15位身份证直接通过
        if (idCard.length() == 15) {
            return true;
        }
        // 18位身份证校验最后一位校验码
        return checkIdCardLastChar(idCard);
    }

    /**
     * 校验车牌号
     */
    public static boolean isLicensePlate(String plate) {
        return match(plate, LICENSE_PLATE_REGEX);
    }

    /**
     * 校验中文姓名
     */
    public static boolean isChineseName(String name) {
        return match(name, CHINESE_NAME_REGEX);
    }

    // ---------------------- 内部工具方法 ----------------------
    
    /**
     * 基础正则匹配方法
     */
    private static boolean match(String input, String regex) {
        if (input == null || input.isEmpty()) {
            return false;
        }
        return Pattern.compile(regex).matcher(input).matches();
    }

    /**
     * 计算18位身份证校验码是否正确
     */
    private static boolean checkIdCardLastChar(String idCard) {
        if (idCard.length() != 18) return false;
        
        // 前17位加权因子
        int[] factors = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        // 校验码对应表
        char[] checkCodes = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
        
        int sum = 0;
        for (int i = 0; i < 17; i++) {
            sum += (idCard.charAt(i) - '0') * factors[i];
        }
        int remainder = sum % 11;
        char actualChar = Character.toUpperCase(idCard.charAt(17));
        return actualChar == checkCodes[remainder];
    }
}